#   Copyright (C) 2008      Tri Tech Information Systems Inc.
# 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
# 
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
# 
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, write to the Free Software Foundation, Inc.,
#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#   
from pyxx.wrapper import ExposedWrapper
from pyxx.formatters import *
from pyxx.callable import BaseFunctionWrapper
from pyxx.parser import QStringList

def find_function(fm, model, cpp_name):
    name_path = cpp_name.split('::')
    function_name = name_path[-1]
    parent_name = name_path[:-1]

    if parent_name:
        string_list = QStringList(parent_name)
        parent_model = model.findItem(string_list, fm)
    else:
        parent_model = fm

    try:
        return parent_model.functionMap[function_name]
    except KeyError:
        raise WrapperError("Could not find %s" % cpp_name)


class FunctionWrapper( ExposedWrapper ):
    WRAPPER_TEMPLATE = '''
    %(declarations)s;
    '''

    wrapper_bases = ""
 
    def __init__(self, wrapper_ctx, fns, module, python_name = None, **kw):
        ExposedWrapper.__init__(self, wrapper_ctx, fns[0], **kw)
        self.module  = module

        self.functions = []
        for fn in fns:
            self.functions.append( BaseFunctionWrapper(fn, None, python_name = python_name, wrapper_ctx = wrapper_ctx) )

    def generate_declarations(self):
        return [fn.generate() + ";" for fn in self.functions]

    def allTypes(self):
        types = set()

        for method in self.functions:
            types.update( method.allTypes() )

        return types            

    def templateTypes( self ):
        """
        Produce a list of template types used in the klass
        """

        types = set(map(str,self.allTypes()))
        types = filter(lambda s: s.find('<') != -1, types)
        return types

    def do_prepare(self):
        for template_type in self.templateTypes():
            if template_type.endswith('const&'):
                template_type = template_type[:-6]
            self.addExtra("expose_template_type< %s >();" % template_type)
